From 02a1394f7e5cd7b01c05f05a0a6b539d4edf490c Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Sat, 6 Mar 2004 15:27:41 +0000 Subject: [PATCH] bitkeeper revision 1.771 (4049ededjtcDNSaY2uNyUCnZr9OuKw) console.c, sched.h: DOM0 now has bidirectional serial console. --- xen/drivers/char/console.c | 8 +++ xen/include/xeno/sched.h | 1 + .../arch/xeno/drivers/console/console.c | 60 ++++++++++++++----- 3 files changed, 53 insertions(+), 16 deletions(-) diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index 6728a32896..370c449423 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -241,6 +241,7 @@ static void serial_rx(unsigned char c, struct pt_regs *regs) if ( c == CTRL_A ) { xen_rx = !xen_rx; + serial_putc(sercon_handle, '\n'); printk("*** Serial input -> %s " "(type 'CTRL-a' to switch input to %s).\n", input_str[xen_rx], input_str[!xen_rx]); @@ -422,6 +423,13 @@ long do_console_write(char *str, unsigned int count) return 0; #else + if ( !test_and_set_bit(PF_CONSOLEWRITEBUG, ¤t->flags) ) + { + printk("DOM%llu is attempting to use the deprecated " + "HYPERVISOR_console_write() interface.\n", current->domain); + printk(" - For testing, create a debug build of Xen\n"); + printk(" - For production, your OS must use the new console model\n"); + } return -ENOSYS; #endif } diff --git a/xen/include/xeno/sched.h b/xen/include/xeno/sched.h index cbfec1cb1c..475b0924ed 100644 --- a/xen/include/xeno/sched.h +++ b/xen/include/xeno/sched.h @@ -39,6 +39,7 @@ extern struct mm_struct init_mm; #define PF_CONSTRUCTED 3 /* Has the guest OS been fully built yet? */ #define PF_IDLETASK 4 /* Is this one of the per-CPU idle domains? */ #define PF_PRIVILEGED 5 /* Is this domain privileged? */ +#define PF_CONSOLEWRITEBUG 6 /* Has this domain used the obsolete console? */ #include #include diff --git a/xenolinux-2.4.25-sparse/arch/xeno/drivers/console/console.c b/xenolinux-2.4.25-sparse/arch/xeno/drivers/console/console.c index 21149a0f9e..f0c475200d 100644 --- a/xenolinux-2.4.25-sparse/arch/xeno/drivers/console/console.c +++ b/xenolinux-2.4.25-sparse/arch/xeno/drivers/console/console.c @@ -41,12 +41,9 @@ static void nonpriv_conwrite(const char *s, unsigned int count) control_if_t *ctrl_if; evtchn_op_t evtchn_op; int src, dst, p; - unsigned long flags; ctrl_if = (control_if_t *)((char *)HYPERVISOR_shared_info + 2048); - spin_lock_irqsave(&xeno_console_lock, flags); - while ( count != 0 ) { /* Wait for the request ring to drain. */ @@ -74,8 +71,6 @@ static void nonpriv_conwrite(const char *s, unsigned int count) s += src; count -= src; } - - spin_unlock_irqrestore(&xeno_console_lock, flags); } static void priv_conwrite(const char *s, unsigned int count) @@ -95,10 +90,13 @@ static void priv_conwrite(const char *s, unsigned int count) static void xen_console_write(struct console *co, const char *s, unsigned int count) { + unsigned long flags; + spin_lock_irqsave(&xeno_console_lock, flags); if ( !(start_info.flags & SIF_INITDOMAIN) ) nonpriv_conwrite(s, count); else priv_conwrite(s, count); + spin_unlock_irqrestore(&xeno_console_lock, flags); } static kdev_t xen_console_device(struct console *c) @@ -167,10 +165,34 @@ static void __do_console_io(void) evtchn_op_t evtchn_op; CONTROL_RING_IDX c; int i, len, work_done = 0; + static char rbuf[16]; - if ( (start_info.flags & SIF_INITDOMAIN) || (xeno_console_tty == NULL) ) + if ( xeno_console_tty == NULL ) return; + /* Special-case I/O handling for domain 0. */ + if ( start_info.flags & SIF_INITDOMAIN ) + { + /* Receive work. */ + while ( (len = HYPERVISOR_serial_io(SERIALIO_read, 16, rbuf)) > 0 ) + for ( i = 0; i < len; i++ ) + tty_insert_flip_char(xeno_console_tty, rbuf[i], 0); + if ( xeno_console_tty->flip.count != 0 ) + tty_flip_buffer_push(xeno_console_tty); + + /* Transmit work. */ + if ( wc != wp ) + { + len = wp - wc; + if ( len > (WBUF_SIZE - WBUF_MASK(wc)) ) + len = WBUF_SIZE - WBUF_MASK(wc); + priv_conwrite(&wbuf[WBUF_MASK(wc)], len); + wc += len; + } + + return; + } + /* Acknowledge the notification. */ evtchn_clear_port(0); @@ -235,6 +257,7 @@ static void __do_console_io(void) } } +/* This is the callback entry point for domains != 0. */ static void control_event(unsigned int port) { unsigned long flags; @@ -243,6 +266,15 @@ static void control_event(unsigned int port) spin_unlock_irqrestore(&xeno_console_lock, flags); } +/* This is the callback entry point for domain 0. */ +static void control_irq(int irq, void *dev_id, struct pt_regs *regs) +{ + unsigned long flags; + spin_lock_irqsave(&xeno_console_lock, flags); + __do_console_io(); + spin_unlock_irqrestore(&xeno_console_lock, flags); +} + static int xeno_console_write_room(struct tty_struct *tty) { return WBUF_SIZE - (wp - wc); @@ -290,13 +322,6 @@ static void xeno_console_flush_buffer(struct tty_struct *tty) static inline int __xeno_console_put_char(int ch) { char _ch = (char)ch; - - if ( start_info.flags & SIF_INITDOMAIN ) - { - priv_conwrite(&_ch, 1); - return 1; - } - if ( (wp - wc) == WBUF_SIZE ) return 0; wbuf[WBUF_MASK(wp++)] = _ch; @@ -345,7 +370,6 @@ static void xeno_console_flush_chars(struct tty_struct *tty) { unsigned long flags; spin_lock_irqsave(&xeno_console_lock, flags); - __do_console_io(); spin_unlock_irqrestore(&xeno_console_lock, flags); } @@ -418,8 +442,12 @@ int __init xeno_con_init(void) { if ( evtchn_request_port(0, control_event) != 0 ) BUG(); - /* Kickstart event delivery. */ - control_event(0); + control_event(0); /* kickstart the console */ + } + else + { + request_irq(_EVENT_CONSOLE, control_irq, 0, "console", NULL); + control_irq(0, NULL, NULL); /* kickstart the console */ } printk("Xeno console successfully installed\n"); -- 2.30.2